package com.YKFuse.wrapper;

import lombok.Data;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @author yuank
 * @version 1.0.0
 * @date 2025/2/11 15:09:35
 *
 * 熔断池包装类 -用于支持 延迟重试 重试计数
 *
 */
@Data
public class MethodDelayWrapper implements Delayed {
    //反射三件套
    private Object bean;
    private Object[] params;
    private Method method;

    //重试支持
    private long expireTime;
    private TimeUnit tryTimeUnit;
    private int canTryTimes;
    private int haveTryTimes;


    public MethodDelayWrapper(Object bean, Object[] params, Method method) {
        // long delay, TimeUnit tryTimeUnit, int canTryTimes
        this.bean = bean;
        this.params = params;
        this.method = method;
        this.haveTryTimes = 0;
    }


    /**
     * 用于计算单个的延迟时间
     */
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(this.expireTime - System.currentTimeMillis(), unit);
    }

    /**
     * 给队列提供排序的作用
     */
    @Override
    public int compareTo(Delayed o) {
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
    }

    public void haveTry() {
        haveTryTimes++;
    }

    public boolean canRetry(){
        return canTryTimes >= haveTryTimes;
    }

    public Object invoke() throws InvocationTargetException, IllegalAccessException {
        return method.invoke(bean, params);
    }
}